package com.tang.consumer.config;

import com.tang.consumer.annotation.EnableRpc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Map;
import java.util.Set;

/**
 * @author Tang
 * @classname RpcScannerConfig
 * @description [  ]
 * @date 2021/1/24 15:36
 */
@Slf4j
public class RpcScannerConfig implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(EnableRpc.class.getName());
        if (attributes != null) {
            ClassPathRpcScanner scanner = new ClassPathRpcScanner(registry);
            Set<BeanDefinitionHolder> beanDefinitionHolders = scanner.doScan(attributes.get("basePackage").toString());
            registerBeanDefinitions(importingClassMetadata,beanDefinitionHolders);
        }
    }

    /**
     * 为spring注入接口代理类
     * @param importingClassMetadata
     * @param beanDefinitionHolders
     */
    void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,Set<BeanDefinitionHolder> beanDefinitionHolders) {
        GenericBeanDefinition definition;
        for (BeanDefinitionHolder beanDefinition : beanDefinitionHolders) {
            definition = (GenericBeanDefinition) beanDefinition.getBeanDefinition();
            definition.getConstructorArgumentValues()
                    .addGenericArgumentValue(definition.getBeanClassName());
            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
            definition.setBeanClass(RpcBeanFactory.class);
        }
    }
}